package org.vectrics.skill;




import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.vectrics.SystemException;
import org.vectrics.common.util.DateSync;
import org.vectrics.evaluation.EvaluationType;
import org.vectrics.hibernate.Filter;
import org.vectrics.hibernate.HibernateUtil;
import org.vectrics.hibernate.Selector;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.job.BranchScore;
import org.vectrics.recruiter.job.Job;
import org.vectrics.recruiter.job.JobCandidateResult;
import org.vectrics.recruiter.job.JobSkillRating;
import org.vectrics.recruiter.job.JobSkillRatingSet;
import org.vectrics.user.Person;
import org.vectrics.user.PersonEncounterStatusType;
import org.vectrics.user.UserSkillRatingSet;



public class SkillPersistMgr extends SkillProvider {
	private transient static Logger log = Logger.getLogger(SkillPersistMgr.class);

	public SkillPersistMgr() {
	}

	public Skill createSkill() {
		return(new Skill());
	}

	public Filter getFilterForCriteria(SkillSearchCriteria criteria, SkillSortMethod skillSortMethod, String[] orderedBy) {
		log.debug("getFilterForCriteria()");
		Filter filter = new Filter();
		filter.setConjunction(Selector.CONJUNTION_AND);
		filter.addFrom("Skill", "skill");
		if (skillSortMethod != null)
		    filter.addOrderBy("skill.description");
		if ((criteria.getRateableSkills()) && (criteria.getNonRateableSkills())) {
			// All skills (rateable/not-rateable) choosen by default
		} else if (criteria.getNonRateableSkills()) {
			filter.addCondition("skill.scoringMethod.code='none'");
		} else if (criteria.getRateableSkills()) {
			filter.addCondition("not skill.scoringMethod.code='none'");
		}
		if (orderedBy != null) {
			for (int i = 0; i < orderedBy.length; i++) {
				filter.addOrderBy(orderedBy[i]);
			}
		}
		return(filter);
	}


	public int findSkillCount(SkillSearchCriteria criteria) {
		Filter filter = this.getFilterForCriteria(criteria, null, null);
		int count = HibernateUtil.findElementCount(filter, "skill");
		return(count);
	}

	public List findSkills(SkillSearchCriteria criteria, int start, int end) {
		String[] orderedBy = {"skill.description"};
		Filter filter = this.getFilterForCriteria(criteria, null, orderedBy);
		filter.addSelectField("skill");
		log.info("findSkills() - statement: " + filter.getStatement());
		List skills = HibernateUtil.findElements(filter, start, end);
		return(skills);
	}


	public Skill getRootSkill() {
	    Skill rootSkill = findSkill("root");
	    if (rootSkill == null) {
	        rootSkill = new Skill();
	        rootSkill.setCode("root");
	        rootSkill.setSection(false);
	        rootSkill.setDescription("Root Skill");
	        rootSkill.setScoringMethod(this.findSkillScoringMethod(SkillScoringMethod.SCORING_METHOD_YES_NO));

	        try {
	            Session session = ThreadProperties.getSession();
	            session.save(rootSkill);
	        } catch (Exception ex) {
	            throw new SystemException("Exception saving skill", ex);
	        }
	        this.updateObject(rootSkill);
	    }
	    return(rootSkill);
	}

	public Skill findSkill(String skillCode) {
		Skill skill = null;
		Session session = null;
		session = ThreadProperties.getSession();
		skill = (Skill)session.load(Skill.class, skillCode);
		if (skill == null)
			throw new SystemException("Could not find skill: " + skillCode);
		return(skill);
	}

	public void updateSkill(Skill updateSkill) {
		Session session = null;
		session = ThreadProperties.getSession();
		log.debug("Updating skill: " + updateSkill);
		session.update(updateSkill);
	}
	
	

	public void saveSkill(Skill updateSkill) {
		if (updateSkill.hasLevelsForScoringMethod(updateSkill.getScoringMethod()) == false) {
			Set defaultScoringLevels = updateSkill.getScoringMethod().getDefaultScoringLevels(updateSkill);
			updateSkill.setScoringLevels(defaultScoringLevels);
			//if (defaultScoringLevels.size() == 0)
			//	throw new SystemException("Could not find any default scoring levels for skill: " + updateSkill.getCode());
		}
		Session session = null;
		session = ThreadProperties.getSession();
		log.debug("Updating skill: " + updateSkill);
		session.save(updateSkill);
	}

	public JobSkillRatingSet findJobSkillSet(Job job) {
		JobSkillRatingSet ratingSet = new JobSkillRatingSet(job);
		return(findJobSkillSet(ratingSet, job, null));
	}

	public JobSkillRatingSet findJobSkillSet(JobSkillRatingSet ratingSet, Job job, JobSkillRating parent) {
		Session session = null;
		List ratings = null;
		session = ThreadProperties.getSession();
		if (parent == null) {
			ratings = session.createQuery(
				"from JobSkillRating as rating where (rating.job.id = ?) and (rating.parent is null)")
					.setLong(0, job.getId().longValue())
					.list();
		} else {
			ratings = session.createQuery(
					"from JobSkillRating as rating where (rating.job.id = ?) and (rating.parent.id = ?)")
					.setLong(0, job.getId().longValue())
					.setLong(1, parent.getId().longValue())
					.list();
		}

		if (parent == null) {
			log.debug("Found root rating for job rating: jobId = " + job.getId());
			Iterator iter = ratings.iterator();
			if (iter.hasNext()) {
				ratingSet.setRootRating((JobSkillRating)iter.next());
			} else {
				log.debug("No parent rating found for job - jobId = " + job.getId());
			}
			if (iter.hasNext()) {
				throw new SystemException("Found more than one job ratings with null parent: jobId = "
						+ job.getId());
			}
		} else {
			log.debug("Found children for job rating - jobRatingId = " + parent.getId() + "  Child count: " + ratings.size());
			HashSet setOfRatings = new HashSet();
			setOfRatings.addAll(ratings);
			parent.setChildSkillRatings(setOfRatings);
		}

		Iterator iter = ratings.iterator();
		while (iter.hasNext()) {
			JobSkillRating rating = (JobSkillRating)iter.next();
			log.debug("Finding children for job rating: " + rating.getId());
			this.findJobSkillSet(ratingSet, job, rating);
		}
		return(ratingSet);
	}
	

	private void validateJobSkillRating(JobSkillRating rating) {
		log.debug("Validate rating: " + rating.getId());
		rating.setId(null);

		log.debug("Validate children of rating");
		Iterator iter = rating.getChildSkillRatings().iterator();
		while (iter.hasNext()) {
			JobSkillRating childRating = (JobSkillRating)iter.next();
			this.validateJobSkillRating(childRating);
		}
	}

	public void saveJobSkillRatingSet(JobSkillRatingSet ratingSet) {
		ratingSet.getJob().setDateLastSkillRating(DateSync.getCurrentTime());
		RecruitServiceLocator.getJobProvider().updateJob(ratingSet.getJob());

		clearJobSkillSet(ratingSet.getRootRating().getJob());
		this.validateJobSkillRating(ratingSet.getRootRating());

		saveJobSkillRating(ratingSet.getRootRating());
	}

	public void saveJobSkillRating(JobSkillRating rating) {
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			log.debug("Saving the root rating should save all of the children under it.");
			session.save(rating);

		} catch (Exception ex) {
			log.error("Exception in saveUserSkillRatingSet(): " + rating.getSkill().getCode(), ex);
			throw new SystemException("Exception in saveJobSkillRatingSet()", ex);
		}
		finally {
		}
		Iterator iter = rating.getChildSkillRatings().iterator();
		while (iter.hasNext()) {
			JobSkillRating child = (JobSkillRating)iter.next();
			this.saveJobSkillRating(child);
		}
	}

	public void updateJobSkillRating(JobSkillRating rating) {
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			log.debug("Saving the root rating should save all of the children under it.");
			session.update(rating);
		} catch (Exception ex) {
			log.error("Exception in saveUserSkillRatingSet(): " + rating.getSkill().getCode(), ex);
			throw new SystemException("Exception in saveJobSkillRatingSet()", ex);
		}
		finally {
		}
	}


	public void clearJobSkillSet(Job job) {
		JobSkillRatingSet set = findJobSkillSet(job);
		if (set.getRootRating() != null)
			deleteJobSkillRating(set.getRootRating());
	}


	private void deleteJobSkillRating(JobSkillRating rating) {
		Iterator iter = rating.getChildSkillRatings().iterator();
		while (iter.hasNext()) {
			JobSkillRating childRating = (JobSkillRating)iter.next();
			deleteJobSkillRating(childRating);
		}

		Session session = null;
		try {
			session = ThreadProperties.getSession();
			session.delete(rating);
		}
		catch (Exception he) {
			log.error("Exception in clearJobSkillSet()", he);
			throw new SystemException("Exception in clearJobSkillSet()", he);
		}
		finally {
		}
	}


	public UserSkillRatingSet findUserSkillSet(UserEvaluation evaluation) {
		if (evaluation == null)
			throw new SystemException("evaluation passed to method is null");
		
		UserSkillRatingSet ratingSet = new UserSkillRatingSet(evaluation.getPerson());

		Session session = null;

		session = ThreadProperties.getSession();
		List ratings = session.createQuery(
				"from UserSkillRating as rating where (rating.evaluation.id = ?)")
				.setLong(0, evaluation.getId().longValue())
						.list();
		Iterator iter = ratings.iterator();
		while (iter.hasNext()) {
			UserSkillRating rating = (UserSkillRating)iter.next();
			ratingSet.getSkillRatings().add(rating);
		}
		return(ratingSet);
	}
	

	public void clearUserSkillSet(UserEvaluation evaluation) {
		Session session = null;
		session = ThreadProperties.getSession();
		SkillRatingSet set = findUserSkillSet(evaluation);
		Collection evals = set.getSkillRatings();
		Iterator iter = evals.iterator();
		while (iter.hasNext()) {
			UserSkillRating rating = (UserSkillRating)iter.next();
			session.delete(rating);
		}
	}

	public void updateObject(Object object) {
		Session session = null;
		session = ThreadProperties.getSession();
		session.saveOrUpdate(object);
	}

	public void clearPersonSkillScores(Person person) {
		if (person.getId() == null)
			throw new SystemException("Exception clearing person skill scores, person has null id (may not have been saved)");
		Session session = null;
		session = ThreadProperties.getSession();
		Iterator iter = session.createQuery("from PersonSkillScore as score where score.person.id = ?")
			.setLong(0, person.getId().longValue())
			.iterate();
		HibernateUtil.deleteObjects(iter, ThreadProperties.getSession());
	}


	public PersonSkillScoreSet findPersonSkillScoreSet(Person person) {
		Session session = null;
		PersonSkillScoreSet scoreSet = new PersonSkillScoreSet();
		try {
			session = ThreadProperties.getSession();
			List scores = session.createQuery(
					"from PersonSkillScore as score where score.person.id = ?")
					.setLong(0, person.getId().longValue())
					.list();
			scoreSet.addAll(scores);
		}
		catch (Exception he) {
			throw new SystemException("Exception in findUserSkillSet()", he);
		}
		finally {
		}
		return(scoreSet);
	}

	public void calculatePersonScores(Person person, UserEvaluation evaluation) {
		//UserEvaluation evaluation = this.findLatestUserSelfEvaluation(person);
		UserSkillRatingSet userSkills = this.findUserSkillSet(evaluation);
		PersonSkillScoreSet allPersonScores = new PersonSkillScoreSet();
		Skill rootSkill = this.getRootSkill();
		Iterator iter = rootSkill.getChildren().iterator();
		while (iter.hasNext()) {
			Skill childSkill = (Skill)iter.next();
			this.calculatePersonScores(person, childSkill, allPersonScores, userSkills);
		}
	}

	public void calculatePersonScores(Person person, Skill parentSkill,
			PersonSkillScoreSet allPersonScores,
				UserSkillRatingSet userSkills) {
		log.debug("getBranchScore() - skill = " + parentSkill.getCode());
		BranchScore scoreAndMaximum = new BranchScore();
		Iterator childSkillIter = parentSkill.getChildren().iterator();
		while (childSkillIter.hasNext()) {
			Skill childSkill = (Skill)childSkillIter.next();
			calculatePersonScores(person, childSkill, allPersonScores, userSkills);
		}

		if (false == parentSkill.getScoringMethod().getCode().equals(SkillScoringMethod.SCORING_METHOD_NONE)) {
			// Person score is based on rating (no calculation needed)
			SkillRating skillRating = userSkills.findSkillRating(parentSkill);
			if ((skillRating != null) && (skillRating.getScore() > 0)) {
				PersonSkillScore personSkillScore = new PersonSkillScore();
				personSkillScore.setPerson(person);
				personSkillScore.setSkill(parentSkill);
				long scoreValue = skillRating.getScore();
				personSkillScore.setScore(new Long(scoreValue));
				this.updatePersonSkillScore(personSkillScore);
				allPersonScores.add(personSkillScore);
			}
		} else {
			childSkillIter = parentSkill.getChildren().iterator();
			long childTotalScore = 0;
			long maximumScore = 0;
			TreeSet additiveScores = new TreeSet(new PersonSkillScoreCompare());
			while (childSkillIter.hasNext()) {
				Skill childSkill = (Skill)childSkillIter.next();

				//long childScore = 0;
				long maxChildScore = 100;
				long childWeight = childSkill.getWeight();

				PersonSkillScore childPersonSkillScore = allPersonScores.findPersonSkillScore(childSkill);
				if (childPersonSkillScore == null) {
					// Make a temporary score, that will not be saved, but will aid in maximum calc for additive
					childPersonSkillScore = new PersonSkillScore();
					childPersonSkillScore.setPerson(person);
					childPersonSkillScore.setScore(new Long(0));
					childPersonSkillScore.setSkill(childSkill);
				}


				if (parentSkill.getChildConjunctionType() == Skill.CONJUNCTION_ADDITIVE) {
					additiveScores.add(childPersonSkillScore);
				} else {
					if (childPersonSkillScore != null) {
						if (childPersonSkillScore.getScore().longValue() > childTotalScore) {
							childTotalScore = childPersonSkillScore.getScore().longValue();
						}
						if (maxChildScore > maximumScore) {
							maximumScore = maxChildScore;
						}
					}
				}
			}

			if ((parentSkill.getScoringMethod().getCode().equals(SkillScoringMethod.SCORING_METHOD_NONE) == true)
					&& (parentSkill.getChildConjunctionType() == Skill.CONJUNCTION_ADDITIVE)) {
				List additiveScoreList = new ArrayList();
				List additiveMaximumScoreList = new ArrayList();
				additiveScoreList.addAll(additiveScores);
				long decayLevel = 0;
				long decayFactor = 100;
				if (parentSkill.getAdditiveDecay() != null) {
					decayLevel = parentSkill.getAdditiveDecay().longValue();
				}

				maximumScore = 0;
				childTotalScore = 0;
				for (int i = additiveScoreList.size() - 1; i >= 0; i--) {
					PersonSkillScore calcChildScore =
						(PersonSkillScore)additiveScoreList.get(i);
					Long childScore = calcChildScore.getScore();
					//Long maxChildScore = calcChildScore.getMaximumScore();

					maximumScore += (((100  * decayFactor)/ 100) * calcChildScore.getSkill().getWeight()) / 100;
					childTotalScore += (((childScore.longValue()  * decayFactor)/ 100) * calcChildScore.getSkill().getWeight()) / 100;
					decayFactor = decayFactor - ((decayFactor * decayLevel) / 100);
					log.debug("Decay level: " + decayLevel);
					log.debug("Decay Factor: " + decayFactor);
					log.debug("Additive Child score: " + childScore);
					log.debug("Additive Max child score: " + maximumScore);
				}
			}

			log.debug("Total Maximum score = " + maximumScore);
			log.debug("Child total score = " + childTotalScore);
			if (childTotalScore > 0) {
				PersonSkillScore personSkillScore = new PersonSkillScore();
				personSkillScore.setPerson(person);
				long scoreValue = ((100 * childTotalScore)/ maximumScore);
				personSkillScore.setScore(new Long(scoreValue));
				personSkillScore.setSkill(parentSkill);
				this.updatePersonSkillScore(personSkillScore);
				allPersonScores.add(personSkillScore);
			}
		}

	}

	public void updatePersonSkillScore(PersonSkillScore personSkillScore) {
		Session session = ThreadProperties.getSession();
		session.saveOrUpdate(personSkillScore);
	}

	public void saveUserSkillRatingSet(UserEvaluation evaluation, UserSkillRatingSet ratingSet) {
		clearPersonSkillScores(evaluation.getPerson());
		clearUserSkillSet(evaluation);
		Session session = null;
		session = ThreadProperties.getSession();
		Collection evals = ratingSet.getSkillRatings();
		Iterator iter = evals.iterator();
		while (iter.hasNext()) {
			UserSkillRating rating = (UserSkillRating)iter.next();
			if (false == rating.getSkill().getScoringMethod().getCode().equals(SkillScoringMethod.SCORING_METHOD_NONE)) {
				UserSkillRating userRating = new UserSkillRating();
				userRating.setEvaluation(evaluation);
				userRating.setSkill(rating.getSkill());
				userRating.setScoringMethod(rating.getScoringMethod());
				userRating.setLevel(rating.getLevel());
				userRating.setPerson(evaluation.getPerson());
				userRating.setViewChildren(rating.getViewChildren());
				if (userRating.getSkillScoringLevel() == null) {
					throw new SystemException("Could not find scoring level for rating, skill: " + rating.getSkill().getCode());
				}

				session.save(userRating);
			}
		}
		calculatePersonScores(evaluation.getPerson(), evaluation);
	}

	public void updateEvaluation(UserEvaluation userEval) {
		Session session = null;
		
		try {
			session = ThreadProperties.getSession();
			session.saveOrUpdate(userEval);
		}
		catch (Exception he) {
			throw new SystemException("Exception in updateEvaluation()", he);
		}
		finally {
		}
	}

	public UserEvaluation createEvaluation(Person person, Person evaluator, 
			PersonEncounterStatusType encounterStatus, EvaluationType type, Long score) {
		if (person == null) {
			log.error("person was passed to createEvaluation() as null");
			throw new SystemException("person was passed to createEvaluation() as null");
		}

		UserEvaluation userEval = new UserEvaluation();
		userEval.setPerson(person);
		userEval.setLeadPerson(evaluator);
		userEval.setEncounterStatus(encounterStatus);
		userEval.setType(type);
		userEval.setScore(score);
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			session.save(userEval);
		}
		catch (Exception he) {
			throw new SystemException("Exception in removeSkill()", he);
		} finally {
		}
		return(userEval);
	}

	public SkillRatingSet findLatestUserSkillSet(Person user) {
		SkillRatingSet result = null;

		Date lastDate = null;
		Collection allEvals = findAllUserEvaluations(user);
		Iterator iter = allEvals.iterator();
		while (iter.hasNext()) {
			UserEvaluation eval = (UserEvaluation)iter.next();
			SkillRatingSet ratingSet = this.findUserSkillSet(eval);
			if (ratingSet.findAllSkillRatings().size() > 0) {
				if ((lastDate == null) || (eval.getDateStart().compareTo(lastDate) > 0)) {
					lastDate = eval.getDateStart();
					result = ratingSet;
				}
			}

		}
		return(result);
	}

	public Collection findAllUserEvaluations(Person person) {
		List evals = new Vector();
		Session session = null;
		session = ThreadProperties.getSession();
		log.debug("findUserById() - found list of users with matching ID - should only be one user");
		evals = session.createQuery("from UserEvaluation as eval where (eval.person.id = ?)")
				.setLong(0, person.getId().longValue())
				.list();

		return(evals);
	}

	public UserEvaluation findEvaluationById(Long evaluationId) {
		UserEvaluation eval = null;
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			try {
				eval = (UserEvaluation)session.load(UserEvaluation.class, evaluationId);
			}
			catch (Exception ex) {
				log.error("Exception doing query: ", ex);
				throw new SystemException("Exception findEvaluationById - finding UserEvaluation by id: " + evaluationId, ex);
			}
		}
		catch (Exception he) {
			throw new SystemException("Exception in findEvaluationById()", he);
		}
		return(eval);
	}

	@Override
	public List findUserSelfEvaluations(Person person) {
		List evals = null;
		Session session = null;
		session = ThreadProperties.getSession();
		log.debug("findUserById() - found list of users with matching ID - should only be one user");
		evals = session.createQuery(
				"from UserEvaluation as eval where (eval.person.id = ?) " +
				"and (eval.leadPerson.id = eval.person.id) order by eval.dateStart")
				.setLong(0, person.getId().longValue())
				.list();
		return(evals);
	}

	@Override
	public UserEvaluation findLatestUserSelfEvaluation(Person person) {
		List evals = this.findUserSelfEvaluations(person);
		UserEvaluation eval = null;

		if (evals.size() > 0)
			eval = (UserEvaluation)evals.get(evals.size() - 1);
		return(eval);
	}


	@Override
	public SkillScoringMethod findSkillScoringMethod(String code) {
		SkillScoringMethod method = null;
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			method = (SkillScoringMethod)
				session.load(SkillScoringMethod.class, code);
		}
		catch (Exception he) {
			throw new SystemException("Exception in findSkillScoringMethod() - code = " + code, he);
		}
		return(method);
	}

	
	@Override
	public long findUserSkillLevel(SkillRating userSkillRating) {
		long score = 0;
		try {
			/*
			try {

				log.debug("findUserById() - found list of users with matching ID - should only be one user");
				List scoreLevels = session.find(
						"from UserEvaluation as eval where (eval.person.id = ?) and (eval.evaluator.id = ?) order by eval.datePerformed",
						new Object[] {userSkillRating., person.getId()},
						new Type[] {Hibernate.LONG, Hibernate.LONG});

			}
			catch (Exception ex) {
				log.error("Exception doing query: ", ex);
				throw new SystemException("Exception doing query: ", ex);
			}
			*/
		}
		catch (Exception he) {
			throw new SystemException("Exception in findUserSelfEvaluations()", he);
		}

		return(score);
	}

	@Override
	public void updateJobCandidateResult(JobCandidateResult result) {
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			session.saveOrUpdate(result);
		}
		catch (Exception he) {
			throw new SystemException("Exception updating JobCandidateResult()", he);
		} 
	}

	/*
	 * 
	 * @see org.vectrics.skill.SkillProvider#findJobCandidateResult(org.vectrics.recruiter.job.Job, org.vectrics.user.Person)
	 */
	@Override
	public JobCandidateResult findJobCandidateResult(Job job, Person candidate) {
		JobCandidateResult result = null;
		Session session = null;
		try {
			session = ThreadProperties.getSession();
			Collection results = session.createQuery(
					"from JobCandidateResult as result where (result.job.id = ?) and (result.person.id = ?)")
					.setLong(0, job.getId().longValue())
					.setLong(1, candidate.getId().longValue())
					.list();
			if (results.size() > 1) {
				throw new SystemException("More than one result returned for job candidate result");
			} else if (results.size() == 1) {
				result = (JobCandidateResult)results.iterator().next();
			}
		}
		catch (Exception he) {
			throw new SystemException("Exception updating JobCandidateResult()", he);
		}
		return(result);
	}

	@Override
	public UserSkillRating findUserSkillRating(UserEvaluation evaluation, Skill skill) {
		UserSkillRating rating = null; 
		Filter filter = new Filter();
		filter.addFrom("UserSkillRating", "skillRating");
		filter.addSelectField("skillRating");
		filter.addParameterCondition("skillRating.skill.id", "=", skill.getId());
		filter.addParameterCondition("skillRating.evaluation.id", "=", evaluation.getId());
		Query query = filter.createQuery(ThreadProperties.getSession());
		List result = query.list();
		if (result.size() == 1) {
			rating = (UserSkillRating)result.iterator().next();
		} else if (result.size() > 1) {
			throw new SystemException("Found more than one rating for evaluation and skil" +
					"\r\n - evaluation = " + evaluation
					+ "\r\n - skill = " + skill);
		} else {
			log.debug("No skill rating found for evaluation and skill, returning null");
		}
		return(rating);
	}

	/**
	 * @see org.vectrics.skill.SkillProvider#getTypeEvaluation();
	 */
	@Override
	public List<EvaluationType> getTypeEvaluation() {
		Session session = ThreadProperties.getSession();
		return session.createQuery("from EvaluationType").list();
	}

	/**
	 * @see org.vectrics.skill.SkillProvider#getTypeEvaluation(java.lang.Long);
	 */
	@Override
	public EvaluationType getTypeEvaluation(Long idType) {
		Session session = ThreadProperties.getSession();
		return (EvaluationType) session.get(EvaluationType.class, idType);
	}
	
}
